#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "MSTK.h"

#ifdef __cplusplus
extern "C" {
#endif
  /*
    this function build ghost and ut list
    and sort them by global id

  */

int MESH_Surf_BuildGhostList(Mesh_ptr mesh);
int MESH_Vol_BuildGhostList(Mesh_ptr mesh);

int MESH_BuildGhostList(Mesh_ptr mesh) {
  int nf, nr;
  /* basic mesh information */
  nf = MESH_Num_Faces(mesh);
  nr = MESH_Num_Regions(mesh);

  if (nr) 
    MESH_Vol_BuildGhostList(mesh);
  else if(nf)
    MESH_Surf_BuildGhostList(mesh);
  else {
    fprintf(stdout,"\nThis is not a valid mstk file to build ghost list\n");
    exit(-1);
  }
  return 1;
}


int MESH_Surf_BuildGhostList(Mesh_ptr mesh) {
  int count_ghost,count_ut, idx;
  int nv, nf;
  MVertex_ptr mv;
  MFace_ptr mf;

  nv = MESH_Num_Vertices(mesh);
  nf = MESH_Num_Faces(mesh);

  /* build vertex */
  idx = 0; count_ghost = 0; count_ut = 0;
  while(mv = MESH_Next_Vertex(mesh,&idx)) {
    if(MV_PType(mv) == PGHOST) {
      count_ghost++;
      MESH_Add_GhostVertex(mesh,mv);
    }
    if(MV_PType(mv) == PUTILIZED) {
      count_ut++;
      MESH_Add_UtVertex(mesh,mv);
    }
  }
  printf("num of vertex %d , ghost vertex %d, ut vertex %d\n",nv, count_ghost, count_ut);  

  /* build face */
  idx = 0; count_ghost = 0; count_ut = 0;
  while(mf = MESH_Next_Face(mesh,&idx)) {
    if(MF_PType(mf) == PGHOST) {
      count_ghost++;
      MESH_Add_GhostFace(mesh,mf);
    }
    if(MF_PType(mf) == PUTILIZED) {
      count_ut++;
      MESH_Add_UtFace(mesh,mf);
    }
  }
  /* sort based on global ID*/
  if(MESH_Num_GhostVertices(mesh))
    List_Sort(MESH_GhostVertex_List(mesh),MESH_Num_GhostVertices(mesh),sizeof(MVertex_ptr),compareGlobalID);
  if(MESH_Num_GhostFaces(mesh))
    List_Sort(MESH_GhostFace_List(mesh),MESH_Num_GhostFaces(mesh),sizeof(MFace_ptr),compareGlobalID);
  if(MESH_Num_UtVertices(mesh))
    List_Sort(MESH_UtVertex_List(mesh),MESH_Num_UtVertices(mesh),sizeof(MVertex_ptr),compareGlobalID);
  if(MESH_Num_UtFaces(mesh))
    List_Sort(MESH_UtFace_List(mesh),MESH_Num_UtFaces(mesh),sizeof(MFace_ptr),compareGlobalID);

  printf("num of face %d , ghost face %d, ut face %d\n",nf, count_ghost, count_ut);  

  return 1;
}

int MESH_Vol_BuildGhostList(Mesh_ptr mesh) {
  int count_ghost,count_ut, idx;
  int nv, nr;
  MVertex_ptr mv;
  MRegion_ptr mr;

  nv = MESH_Num_Vertices(mesh);
  nr = MESH_Num_Regions(mesh);

  /* build vertex */
  idx = 0; count_ghost = 0; count_ut = 0;
  while(mv = MESH_Next_Vertex(mesh,&idx)) {
    if(MV_PType(mv) == PGHOST) {
      count_ghost++;
      MESH_Add_GhostVertex(mesh,mv);
    }
    if(MV_PType(mv) == PUTILIZED) {
      count_ut++;
      MESH_Add_UtVertex(mesh,mv);
    }
  }
  printf("num of vertex %d , ghost vertex %d, ut vertex %d\n",nv, count_ghost, count_ut);  

  /* build vertex */
  idx = 0; count_ghost = 0; count_ut = 0;
  while(mr = MESH_Next_Region(mesh,&idx)) {
    if(MR_PType(mr) == PGHOST) {
      count_ghost++;
      MESH_Add_GhostRegion(mesh,mr);
    }
    if(MR_PType(mr) == PUTILIZED) {
      count_ut++;
      MESH_Add_UtRegion(mesh,mr);
    }
  }
  /* sort based on global ID*/
  if(MESH_Num_GhostVertices(mesh))
    List_Sort(MESH_GhostVertex_List(mesh),MESH_Num_GhostVertices(mesh),sizeof(MVertex_ptr),compareGlobalID);
  if(MESH_Num_GhostRegions(mesh))
    List_Sort(MESH_GhostRegion_List(mesh),MESH_Num_GhostRegions(mesh),sizeof(MRegion_ptr),compareGlobalID);
  if(MESH_Num_UtVertices(mesh))
    List_Sort(MESH_UtVertex_List(mesh),MESH_Num_UtVertices(mesh),sizeof(MVertex_ptr),compareGlobalID);
  if(MESH_Num_UtRegions(mesh))
    List_Sort(MESH_UtRegion_List(mesh),MESH_Num_UtRegions(mesh),sizeof(MRegion_ptr),compareGlobalID);
  
  printf("num of region %d , ghost region %d, ut region %d\n",nr, count_ghost, count_ut);  

  return 1;
}


#ifdef __cplusplus
}
#endif

